#lang rosetta-racket


(provide pipe-walk)


(define (round-c c)
  (xyz
   (round (xyz-x c))
   (round (xyz-y c))
   (round (xyz-z c))))

(define random-interval-round (λ. round random-interval))

(define (pipe-walk c v0 l n valid-fn)
  (define (pipe-walk-rec c v0 n)
    (if (= n 0)
        (list)
        (let ((v1 (round-c
                   (sph
                    1
                    (* (random-interval-round 0 4) pi/2)
                    (* (random-interval-round 0 3) pi/2)))))
          (cond ((=c v0 (*c v1 -1))
                 (pipe-walk-rec c v0 n))
                (else
                 (let ((top-c (+c c (*c v1 (* (random-interval 0.2 1.0) l)))))
                   (cond ((valid-fn top-c)
                          (list*
                           (cylinder c (* 0.02 l) top-c)
                           (sphere top-c (* 0.04 l))
                           (pipe-walk-rec top-c v1 (- n 1))))
                         (else
                          (pipe-walk-rec c v0 n)))))))))
  
  (pipe-walk-rec c v0 n))